#include "IpV6Address.h"
#include <arpa/inet.h>
#include <string>
#include "BytesEndian.h"
#include "SocketOpt.h"
#include "Util.h"
namespace xncc {
namespace foundation {

    IpV6Address::IpV6Address(const std::string& addr, int protocol) : protocol_(protocol)
    {
        auto        pos      = addr.find_last_of(':');
        std::string port_str = addr.substr(pos + 1);
        std::string ip_str   = addr.substr(0, pos);

        auto port = static_cast<uint16_t>(std::stoi(port_str));
        shared::memZero(addr_);
        addr_.sin6_family = AF_INET6;
        addr_.sin6_port   = hostToNetwork16(port);
        if (::inet_pton(AF_INET6, ip_str.data(), &addr_.sin6_addr) <= 0) {
            throw shared::logic_exception(std::string("is not valid ipv6 addr ") + shared::strerror_tl(errno));
        }
    }

    IpV6Address::IpV6Address(const struct sockaddr_in6& addr, int protocol) : addr_(addr), protocol_(protocol) {}

    IpV6Address::IpV6Address(int protocol) : protocol_(protocol) {}

    IpV6Address::~IpV6Address() = default;

    std::string IpV6Address::toIpPort() const { return SocketOpt::toIpPort(getSockAddr()); }

    std::string IpV6Address::toIp() const { return SocketOpt::toIp(getSockAddr()); }

    uint16_t IpV6Address::toPort() const { return networkToHost16(addr_.sin6_port); }
}  // namespace foundation
}  // namespace xncc